/////////////////////////////////////////////////////////////
// File Name		: "Game.cpp"
// 
// Author Name		:  Cristhian De La Paz
//
// Purpose			: To encapsulate all game related code.
/////////////////////////////////////////////////////////////
#include "Game.h"
#include "MainMenuState.h"
#include "CGamePlayState.h"

CGame::CGame()
{
	m_pD3D = NULL;
	m_pFM = NULL;
	m_pTM = NULL;
	m_pDI = NULL;

	m_pCurState = NULL;

	m_nImageID = -1;
	m_nSoundID = -1;
	m_dwFPSTimeStamp = GetTickCount();
	m_dwPreviousTimeStamp = GetTickCount();
}

CGame::~CGame()
{

}

CGame* CGame::GetInstance() /*gives us access to the singleton. */
{
	static CGame instance;
	return &instance;
}

//1. Initialization of the game class
void CGame::Initialize(HWND hwnd, HINSTANCE hInstance, int nWinWidth, int nWinHeight, bool isWindowed, bool isVSync)
{
	m_pD3D = CSGD_Direct3D::GetInstance();
	m_pFM = CSGD_FModManager::GetInstance();
	m_pTM = CSGD_TextureManager::GetInstance();
	m_pDI = CSGD_DirectInput::GetInstance();

	m_nWindowWidth = nWinWidth;
	m_nWindowHeight = nWinHeight;

	m_pD3D->InitDirect3D(hwnd, nWinWidth, nWinHeight, isWindowed, isVSync);
	m_pTM->InitTextureManager(m_pD3D->GetDirect3DDevice(), m_pD3D->GetSprite());
	m_pDI->InitDirectInput(hwnd, hInstance, DI_KEYBOARD | DI_MOUSE, 0);
	m_pFM->InitFModManager(hwnd);

	m_nWindowWidth = nWinWidth;
	m_nWindowHeight = nWinHeight;

	ChangeState(CMainMenuState::GetInstance());
	m_dwFPSTimeStamp = GetTickCount();
	m_dwPreviousTimeStamp = GetTickCount();
	m_fTotalElapsedTime = 0.0f;
}

//3. Shutdown all relevant game code
void CGame::Shutdown()
{
	ChangeState(NULL);

	if(m_pFM)
	{
		m_pFM->ShutdownFModManager();
		m_pFM = NULL;
	}

	if(m_pDI)
	{
		m_pDI->ShutdownDirectInput();
		m_pDI = NULL;
	}

	if(m_pTM)
	{
		m_pTM->ShutdownTextureManager();
		m_pTM = NULL;
	}
	
	if(m_pD3D)
	{
		m_pD3D->ShutdownDirect3D();
		m_pD3D = NULL;
	}
	
}

//2. Execution of game code.
bool CGame::Execute()
{
	if (Input() == false)
		return false;

	Update();

	Render();

	return true;
}

bool CGame::Input()
{
	if(m_pDI->KeyDown(DIK_LALT) || m_pDI->KeyDown(DIK_RALT))
		if(m_pDI->KeyPressed(DIK_RETURN))			
			m_pD3D->ChangeDisplayParam(m_nWindowWidth, m_nWindowHeight, m_bIsWindowed = !m_bIsWindowed);

	if(m_pCurState)
		if(m_pCurState->Input() == false)
			return false;

	return true;
}

void CGame::Update()
{
	DWORD dwStartTimeStamp = GetTickCount();
	m_fElapsedTime = (float)((dwStartTimeStamp - m_dwPreviousTimeStamp) / 1000.0f);
	m_dwPreviousTimeStamp = dwStartTimeStamp;
	m_fTotalElapsedTime += m_fElapsedTime;
	m_pFM->Update();
	if(m_pCurState)
		m_pCurState->Update();
}

void CGame::Render()
{
	m_pD3D->Clear(0, 0, 128);

	m_pD3D->DeviceBegin();

	m_pD3D->SpriteBegin();

	if(m_pCurState)
		m_pCurState->Render();
	m_pD3D->GetSprite()->Flush();
	//print out the amount of ellapsed time
	/*char buffer[128]= {0};
	sprintf_s(buffer, _countof(buffer), "Elapsed Time:  %.3f", m_fTotalElapsedTime);
	m_pD3D->DrawTextA(buffer, 100, 100);*/
	m_pD3D->SpriteEnd();

	m_pD3D->DeviceEnd();

	m_pD3D->Present();
}

void CGame::ChangeState( IGameState* pNewState )
{
	if(m_pCurState)
		m_pCurState->Exit();

	m_pCurState = pNewState;

	if(m_pCurState)
		m_pCurState->Enter();
}

void CGame::SetWindowSize( int nWindowWidth, int nWindowHeight )
{
	m_nWindowWidth = nWindowWidth;
	m_nWindowHeight = nWindowHeight;
}

int CGame::GetWindowWidth()
{
	return m_nWindowWidth;
}

int CGame::GetWindowHeight()
{
	return m_nWindowHeight;
}
